/**
 * Copyright (c) 2008, Gaudenz Alder
 */
package com.mxgraph.swing.handler;

import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.swing.util.mxMouseAdapter;

import java.awt.*;
import java.awt.event.MouseEvent;

/**
 * The type Mx panning handler.
 */
public class mxPanningHandler extends mxMouseAdapter {

    /**
     *
     */
    private static final long serialVersionUID = 7969814728058376339L;

    /**
     * The Graph component.
     */
    protected mxGraphComponent graphComponent;

    /**
     * The Enabled.
     */
    protected boolean enabled = true;

    /**
     * The Start.
     */
    protected transient Point start;

    /**
     * Instantiates a new Mx panning handler.
     *
     * @param graphComponent the graph component
     */
    public mxPanningHandler(mxGraphComponent graphComponent) {
        this.graphComponent = graphComponent;

        graphComponent.getGraphControl().addMouseListener(this);
        graphComponent.getGraphControl().addMouseMotionListener(this);
    }

    /**
     * Is enabled boolean.
     *
     * @return the boolean
     */
    public boolean isEnabled() {
        return enabled;
    }

    /**
     * Sets enabled.
     *
     * @param value the value
     */
    public void setEnabled(boolean value) {
        enabled = value;
    }

    /**
     *
     */
    public void mousePressed(MouseEvent e) {
        if (isEnabled() && !e.isConsumed() && graphComponent.isPanningEvent(e) && !e.isPopupTrigger()) {
            start = e.getPoint();
        }
    }

    /**
     *
     */
    public void mouseDragged(MouseEvent e) {
        if (!e.isConsumed() && start != null) {
            int dx = e.getX() - start.x;
            int dy = e.getY() - start.y;

            Rectangle r = graphComponent.getViewport().getViewRect();

            int right = r.x + ((dx > 0) ? 0 : r.width) - dx;
            int bottom = r.y + ((dy > 0) ? 0 : r.height) - dy;

            graphComponent.getGraphControl().scrollRectToVisible(
                    new Rectangle(right, bottom, 0, 0));

            e.consume();
        }
    }

    /**
     *
     */
    public void mouseReleased(MouseEvent e) {
        if (!e.isConsumed() && start != null) {
            int dx = Math.abs(start.x - e.getX());
            int dy = Math.abs(start.y - e.getY());

            if (graphComponent.isSignificant(dx, dy)) {
                e.consume();
            }
        }

        start = null;
    }

    /**
     * Whether or not panning is currently active
     *
     * @return Whether or not panning is currently active
     */
    public boolean isActive() {
        return (start != null);
    }
}
